<template>
	{{ contentValue }}
</template>

<script setup>
import { ref, computed, unref, watch } from "vue"
import { useDictStore } from "/store/dict"

const props = defineProps({
	placeholder: {
		type: String,
		default: "",
	},
	dict: {
		type: [String, Array],
	},
	label: {
		type: String,
	},
	value: {
		type: String,
	},
	spacer: {
		type: String,
		default: ",",
	},
	join: {
		type: String,
	},
	content: {
		type: [String, Number],
		default: "",
	},
	password: {
		type: [Boolean, Object],
		default: false,
	},
})

const contentValue = ref(props.placeholder)
const labelKey = computed(() => {
	if (props.label) {
		return props.label
	}
	return "name"
})
const valueKey = computed(() => {
	if (props.value) {
		return props.value
	}
	return "code"
})
const optionsList = ref([])
function refreshOptionsList() {
	return new Promise(resolve => {
		if (typeof props.dict === "string") {
			const dictStore = useDictStore()
			dictStore.getDict(props.dict).then(resule => {
				resolve(resule.map(item => ({ ...item, [valueKey.value]: item[valueKey.value] + "" })))
			})
		} else {
			resolve(props.dict.map(item => ({ ...item, [valueKey.value]: item[valueKey.value] + "" })))
		}
	})
}

const passwordOptions = computed(() => {
	if (typeof props.password === "object") {
		return props.password
	}
	return { start: 3, end: 4 }
})

async function setContent(value) {
	optionsList.value = await refreshOptionsList()
	let content = unref(value)
	if (typeof content === "string" || typeof content === "number") {
		content = (content + "").split(props.spacer)
	}
	contentValue.value = content
		.map(value => {
			let returnValue = value + ""
			if (props.dict) {
				const data = optionsList.value.find(item => item[valueKey.value] === value)
				if (data) {
					returnValue = data[labelKey.value]
				}
			}
			if (props.password) {
				let start = passwordOptions.value.start || 3
				let end = passwordOptions.value.end || 4

				if (start + end > returnValue.length) {
					start = 0
					end = 0
				}
				const starLength = passwordOptions.value.length ?? returnValue.length - start - end
				const star = new Array(starLength).fill("*").join("")

				returnValue = returnValue.slice(0, start) + star + (end ? returnValue.slice(end * -1) : "")
			}
			return returnValue
		})
		.join(props.join || props.spacer)
}
if (props.content) {
	setContent(props.content)
}

watch(
	() => props.content,
	() => {
		if (props.content) {
			setContent(props.content)
		} else {
			contentValue.value = ""
		}
	}
)
</script>

<style lang="scss" scoped></style>
